﻿using CoreModule;
using HandyControl.Controls;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Media;

namespace Yuwell.AtomizerWeight.App.Views
{
    /// <summary>
    /// HistoryWindow.xaml 的交互逻辑
    /// </summary>
    public partial class HistoryWindow : System.Windows.Window
    {
        /// <summary>
        /// 
        /// </summary>

        public static int DataCountPerPage = 10;
        public HistoryWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnSearch_Click(object sender, RoutedEventArgs e)
        {

            RefreshMeasurementResultInfos();

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnSecondary_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            var btn = sender as System.Windows.Controls.Button;
            btn.Background = new SolidColorBrush(Color.FromRgb(0xF1, 0xF0, 0xF5));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnSecondary_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            var btn = sender as System.Windows.Controls.Button;
            btn.Background = new SolidColorBrush(Colors.Transparent);
        }

        private void datePicker_Start_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
        {
            var start = datePicker_Start.SelectedDate;

            if (start.HasValue)
            {
                this.datePicker_End.BlackoutDates.Clear();
                this.datePicker_End.BlackoutDates.Add(new CalendarDateRange(DateTime.MinValue, start.Value.AddDays(-1)));
            }
            else
            {
                this.datePicker_End.BlackoutDates.Clear();
            }
            this.datePicker_Start.BlackoutDates.Add(new CalendarDateRange(DateTime.Now.AddDays(1), DateTime.MaxValue));

            this.datePicker_End.BlackoutDates.Add(new CalendarDateRange(DateTime.Now.AddDays(1), DateTime.MaxValue));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void datePicker_End_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
        {
            var end = datePicker_End.SelectedDate;

            if (end.HasValue)
            {

                this.datePicker_Start.BlackoutDates.Add(new CalendarDateRange(end.Value.AddDays(1), DateTime.MaxValue));
            }
            else
            {
                this.datePicker_Start.BlackoutDates.Clear();
            }

            this.datePicker_Start.BlackoutDates.Add(new CalendarDateRange(DateTime.Now.AddDays(1), DateTime.MaxValue));

            this.datePicker_End.BlackoutDates.Add(new CalendarDateRange(DateTime.Now.AddDays(1), DateTime.MaxValue));
        }

        /// <summary>
        /// 
        /// </summary>
        public void RefreshMeasurementResultInfos(int pageIndex = 0)
        {
            try
            {
                if (pageIndex == 0)
                {
                    this.pgtList.PageIndex = 1;
                }
                var startTime = this.datePicker_Start.SelectedDate;

                var endTime = this.datePicker_End.SelectedDate;

                var dbStorage = new CoreModule.Storages.MySqlDbStorage();
                var query = dbStorage.MeasurementResultInfos
                    .Where(item => startTime.HasValue ? item.RefTime >=
                       new DateTime(startTime.Value.Year, startTime.Value.Month, startTime.Value.Day, 0
                    , 0, 0) : true)
                    .Where(item => endTime.HasValue ? item.RefTime <=
                       new DateTime(endTime.Value.Year, endTime.Value.Month, endTime.Value.Day, 0, 0, 0).AddDays(1) : true);

                var count = query.Count();

                this.UpdateMaxPageCount(count);

                this.txtEntityTotalCount.Text = count.ToString();
                this.lvMeasurementResultInfos.ItemsSource = query
                    .OrderByDescending(item => item.RefTime)
                    .ThenByDescending(item=>item.StartTime)
                    .Skip(pageIndex * DataCountPerPage)
                    .Take(DataCountPerPage)
                    .ToList();

            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            DefaultPaginationButtonStyle = this.FindResource("DefaultPaginationButtonStyle") as Style;

            UpdatePaginationStyle(this.pgtList);

            RefreshMeasurementResultInfos();


            this.datePicker_Start.SelectedDate = DateTime.Now;
            this.datePicker_End.SelectedDate = DateTime.Now;


            this.datePicker_Start.BlackoutDates.Add(new CalendarDateRange(DateTime.Now.AddDays(1), DateTime.MaxValue));

            this.datePicker_End.BlackoutDates.Add(new CalendarDateRange(DateTime.Now.AddDays(1), DateTime.MaxValue));

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {

        }

        private void Window_Unloaded(object sender, RoutedEventArgs e)
        {

        }

        private void Window_PreviewKeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
        {

        }

        private void Window_Closed(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pgtList_PageUpdated(object sender, HandyControl.Data.FunctionEventArgs<int> e)
        {
            try
            {
                var pageIndex = e.Info - 1;
                RefreshMeasurementResultInfos(pageIndex);
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);
            }


            UpdatePaginationStyle(sender as Pagination);
        }

        /// <summary>
        /// 
        /// </summary>
        Style DefaultPaginationButtonStyle { get; set; } = default(Style);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="pagination"></param>
        private void UpdatePaginationStyle(Pagination pagination)
        {
            var panelMain = (StackPanel)pagination.Template.FindName("PART_PanelMain", pagination);

            foreach (System.Windows.Controls.RadioButton item in panelMain.Children)
            {
                item.Style = DefaultPaginationButtonStyle;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnReset_Click(object sender, RoutedEventArgs e)
        {

            this.datePicker_Start.SelectedDate = DateTime.Now;
            this.datePicker_End.SelectedDate = DateTime.Now;

            this.RefreshMeasurementResultInfos();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnExport_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var startTime = this.datePicker_Start.SelectedDate;

                var endTime = this.datePicker_End.SelectedDate;

                var dbStorage = new CoreModule.Storages.MySqlDbStorage();
                var entities = dbStorage.MeasurementResultInfos
                    .Where(item => startTime.HasValue ? item.RefTime >=
                       new DateTime(startTime.Value.Year, startTime.Value.Month, startTime.Value.Day, 0
                    , 0, 0) : true)
                    .Where(item => endTime.HasValue ? item.RefTime <=
                       new DateTime(endTime.Value.Year, endTime.Value.Month, endTime.Value.Day, 0, 0, 0).AddDays(1) : true)
                      .OrderByDescending(item => item.RefTime)
                      .ThenByDescending(item => item.StartTime)
                      .ToList();


                SaveFileDialog dialog = new SaveFileDialog()
                {
                    Filter = "Excel(*.xlsx *.xls)|*.xlsx;*.xls",
                    FileName = $"测量记录{DateTime.Now.ToString("yyyyMMddHHmmss")}"
                };
                string filePath = "";
                if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    filePath = dialog.FileName;
                }
                var sheetRowCount = 20000;
                if (!string.IsNullOrEmpty(filePath))
                {

                    XSSFWorkbook book = new XSSFWorkbook();
                    for (int i = 0; i < entities.Count; i += sheetRowCount)
                    {
                        CreateSheetForRecord(book, entities.Skip(i).Take(sheetRowCount).ToList());
                    }

                    using (System.IO.FileStream bookStream = new System.IO.FileStream(filePath, System.IO.FileMode.Create))
                    {
                        book.Write(bookStream);
                        bookStream.Close();
                    }

                }
                System.Windows.Forms.MessageBox.Show("导出成功");


            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);
            }

        }

        private void UpdateMaxPageCount(int count)
        {
            if (count == 0)
            {
                this.pgtList.MaxPageCount = 0;
                this.lvMeasurementResultInfos
             .ItemsSource = new List<MeasurementResultInfo>();
            }
            else
            {
                var add = count % DataCountPerPage == 0 ? 0 : 1;

                this.pgtList.MaxPageCount = count / DataCountPerPage + add;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private ISheet CreateSheetForRecord(XSSFWorkbook book, List<MeasurementResultInfo> entities)
        {

            ISheet sheet = book.CreateSheet();
            IRow rowTitle = sheet.CreateRow(0);
            List<string> names = new List<string>();
            names.Add("设备编号");
            names.Add("开始时间");
            names.Add("开始重量(g)");

            names.Add("雾化率");
            names.Add("结束时间");
            names.Add("结束重量(g)");
            names.Add("雾化时间(min)");
            names.Add("结果");

            for (int i = 0; i < names.Count; i++)
            {
                rowTitle.CreateCell(i).SetCellValue(names[i]);
            }
            sheet.DefaultColumnWidth = 10;
            sheet.SetColumnWidth(1, 25 * 256);
            sheet.SetColumnWidth(2, 25 * 256);
            sheet.SetColumnWidth(3, 25 * 256);
            sheet.SetColumnWidth(4, 25 * 256);
            var index = 1;
            foreach (var entity in entities)
            {
                NPOI.SS.UserModel.IRow itRow = sheet.CreateRow(index);
                List<string> cols = new List<string>();

                cols.Add(entity.DeviceSN);
                cols.Add(entity.StartTime.ToString("yyyy-MM-dd HH:mm:ss"));
                cols.Add(entity.StartWeight.ToString("F2"));

                cols.Add(entity.Vapor.ToString());
                cols.Add(entity.EndTime.HasValue ? entity.EndTime.Value.ToString("yyyy-MM-dd HH:mm:ss") : "");
                cols.Add(entity.EndWeight.HasValue ? entity.EndWeight.Value.ToString("F2") : "");
                cols.Add(entity.VaporInterval);
                cols.Add(entity.VaporResult.ToString());

                for (int j = 0; j < cols.Count; j++)
                {
                    itRow.CreateCell(j).SetCellValue(cols[j]);
                }
                index = index + 1;
            }
            return sheet;

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_PreviewKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == System.Windows.Input.Key.F5)
            {
                this.RefreshMeasurementResultInfos();
            }

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var measurementResultInfo = (sender as System.Windows.Controls.Button).Tag as CoreModule.MeasurementResultInfo;

            if (measurementResultInfo == null)
            {
                return;
            }

            if (System.Windows.Forms.MessageBox.Show(string.Format("删除{0}", measurementResultInfo.DeviceSN)) == System.Windows.Forms.DialogResult.OK)
            {
                try
                {
                    CoreModule.Storages.MySqlDbStorage dbStorage = new CoreModule.Storages.MySqlDbStorage();

                    var first = dbStorage.MeasurementResultInfos.FirstOrDefault(item => item.Id == measurementResultInfo.Id);
                    if (first == null)
                    {
                        return;
                    }
                    dbStorage.Attach(first).State = Microsoft.EntityFrameworkCore.EntityState.Deleted;
                    dbStorage.SaveChanges();
                    this.RefreshMeasurementResultInfos();

                }
                catch (Exception ex)
                {

                }

            }

        }
    }
}
